﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using VitCode.ObjectResolutionHelper;

namespace VitCode.ObjectSettingApp
{
    public partial class frmCreateSettingFiles : Form
    {
        public frmCreateSettingFiles()
        {
            InitializeComponent();
        }

        private void ShowMsg(StringCollection sc)
        {
            if (sc == null) return;
            var sb = new StringBuilder();
            foreach (string s in sc)
            {
                sb.Append("\r\n[" + s + "]");
            }
            MessageBox.Show(sb.ToString());
        }

        private void WriteTxt(StringCollection sc, string filePath, bool isApp, Encoding encoding)
        {
            
            if (sc == null) return;
            var tempIndex = 0;
            var endIndex = filePath.IndexOf('\\', tempIndex);
            while(endIndex > -1)
            {
                string dirPath = filePath.Substring(0, endIndex);
                if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
                tempIndex = endIndex + 1;
                endIndex = filePath.IndexOf('\\', tempIndex);
            }
            if (File.Exists(filePath)) File.Delete(filePath);
            var sw = new StreamWriter(filePath, isApp, encoding);
            try
            {
                foreach (string s in sc)
                    sw.WriteLine(s);
            }
            finally
            {
                sw.Close();
                sw.Dispose();
            }
        }
        const string SETTINGS_DIR_PATH = "Settings";

        private void WriteSettingFile(StringCollection sc, string fileName, bool isApp, Encoding encoding)
        {
            WriteTxt(sc, SETTINGS_DIR_PATH + "\\" + fileName, isApp, encoding);
        }

        private string GetDbTableCreateScript(string strAssName,string strNameSpare,StringCollection scMenuScript,StringCollection scWithOutClassName)
        {
            var sb = new StringBuilder();
            int amount = 0;
            var dbSettinghlp = new DbSettingHelper();
            ArrayList ts = LookUpClassHelper.GetTypes(strAssName ,strNameSpare);
            foreach (Type t in ts)
            {
                if (scWithOutClassName != null && scWithOutClassName.Contains(t.Name))
                    continue;
                amount++;
                string str = dbSettinghlp.GetClassContext(t, strAssName.Replace(".", "_"));
                sb.Append(str+"\r\n");
                if (scMenuScript==null)
                    continue;
                string strDes = LookUpClassHelper.GetOrMemoDesValue(t);
                scMenuScript.Add(
                    @"INSERT INTO [VitCode_Castle_Menu]([Id],[Name],[UrlPath],[ParentId]
,[CreateUserId],[LastEditUserId],[LastEditDate],[IsLogicDelete],[Operate],[SortKey])VALUES
(newid() ,'" + strDes + "','../BaseData/ObjList.aspx?ClassName=" + t.Name +
                    "',@ParentId,@adminId,@adminId,GetDate(),0,'Add;Edit;Delete','B" + amount.ToString().PadLeft(2, '0') +
                    "');");
            }
            return sb.ToString();
        }

        private void btnCreateDbSql_Click(object sender, EventArgs e)
        {
            
            var scDbCreateSql = new StringCollection();
            string path = "MappingFiles\\ProjectInitSql.sql";
            if (File.Exists(path))
            {
                var sr = new StreamReader(path);
                try
                {
                    scDbCreateSql.Add(sr.ReadToEnd());
                }
                finally
                {
                    sr.Close();
                    sr.Dispose();
                }
            }
            var scDbCreateMenu = new StringCollection();
            scDbCreateMenu.Add(
                @"go
Declare @adminId uniqueidentifier
select @adminId=Id from VitCode_Castle_User where Code='admin'
Declare @ParentId uniqueidentifier
select @ParentId = Id from VitCode_Castle_Menu where Name='业务功能'");

            scDbCreateSql.Add(GetDbTableCreateScript(txtAssName.Text, txtNameSpare.Text, scDbCreateMenu,null));

            scDbCreateMenu.Add(
                @"go
declare @adminId uniqueidentifier
select @adminId = Id from VitCode_Castle_user where code='admin'

INSERT INTO [VitCode_Castle_Permission]
           ([Id]
           ,[ObjId]
           ,[ObjClassName]
           ,[ResourceId]
           ,[ResourceClassName]
           ,[OperateNum]
           ,[CreateUserId]
           ,[LastEditUserId]
           ,[LastEditDate]
           ,[IsLogicDelete])
select newid() Id,ur.RoleId ObjId,'Role' ObjClassName,m.Id ResourceId,
'Menu' ResourceClassName,'Add;Edit;Delete' OperateNum,
@adminId CreateUserId,@adminId lastEditUserId,getdate() LastEditDate,
1 IsLogicDelete from VitCode_Castle_Menu m
inner join VitCode_Castle_User_Role ur on ur.UserId=@adminId");

            string sqlPath = "CreateDbTableSql_" + txtAssName.Text.Replace(".", "") + ".sql";
            WriteSettingFile(scDbCreateSql, sqlPath, false, Encoding.Default);
            WriteSettingFile(scDbCreateMenu, sqlPath, true, Encoding.Default);

            MessageBox.Show("创建对象DbTable脚本成功");
        }

        private StringCollection GetMappingContext(string assName,string nameSpare,string dbKeyProName)
        {
            var hlp = new MappingSettingHelper();
            ArrayList ts = LookUpClassHelper.GetTypes(assName, nameSpare);
            var sb = new StringBuilder();
            var scFileContext = new StringCollection();
            scFileContext.Add("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" +
                              "<hibernate-mapping xmlns=\"urn:nhibernate-mapping-2.2\" namespace=\"" + nameSpare +
                              "\" assembly=\"" + assName + "\">");
            foreach (Type t in ts)
            {
                if (t.GetProperties().Length == 0) continue;
                string str = hlp.GetClassContext(t, assName, dbKeyProName);
                if(!string.IsNullOrEmpty(str))
                    scFileContext.Add(str);
            }
            scFileContext.Add(@"</hibernate-mapping>");
            return scFileContext;
        }

        private void btnCreateMappingXml_Click(object sender, EventArgs e)
        {
            var scFileContext = GetMappingContext(txtAssName.Text, txtNameSpare.Text,BaseDataKeyInfo.ID);
            WriteSettingFile(scFileContext, txtAssName.Text + ".hbm.xml", false, Encoding.UTF8);
            MessageBox.Show("创建对象 NHibernate Mapping 配置文件成功");
        }


        private void btnCreateBaseDataSetting_Click(object sender, EventArgs e)
        {
            var hlp = new BaseDataSettingHelper(txtAssName.Text);
            ArrayList ts = LookUpClassHelper.GetTypes(txtAssName.Text, txtNameSpare.Text);
            hlp.AssTypes = ts;
            var scFileContext = new StringCollection();
            scFileContext.Add("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" +
                              "<Setting>");
            foreach (Type t in ts)
            {
                string str = hlp.GetClassContext(t);
                scFileContext.Add(str);
            }

            foreach (Type t in hlp.SelObjTypes)
            {
                string assName = LookUpClassHelper.GetAssName(t);
                string str = hlp.GetClassContext(t,assName);
                scFileContext.Add(str);
            }

            scFileContext.Add(@"</Setting>");
            WriteSettingFile(scFileContext, "BaseDataSet.xml", false, Encoding.UTF8);
            MessageBox.Show("创建对象 BaseDataSet 配置文件成功");
        }

        private void btnOpenDir_Click(object sender, EventArgs e)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "Settings";
            Process.Start("explorer.exe", path);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var hlp = new ImportSettingHelper(txtAssName.Text);
            ArrayList ts = LookUpClassHelper.GetTypes(txtAssName.Text, txtNameSpare.Text);
            hlp.AssTypes = ts;
            var scFileContext = new StringCollection();
            scFileContext.Add("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" +
                              "<Setting>");
            foreach (Type t in ts)
            {
                string str = hlp.GetClassContext(t);
                scFileContext.Add(str);
            }
            scFileContext.Add(@"</Setting>");
            WriteSettingFile(scFileContext, "BaseImportSet.xml", false, Encoding.UTF8);
            MessageBox.Show("创建对象 BaseImportSet 配置文件成功");
        }


        private void frmCreateSettingFiles_Load(object sender, EventArgs e)
        {
            if (!Directory.Exists(SETTINGS_DIR_PATH))
            {
                Directory.CreateDirectory(SETTINGS_DIR_PATH);
            }
        }

        private void btnHisClassFiles_Click(object sender, EventArgs e)
        {
            var hlp = new HistorySettingHelper();
            ArrayList ts = LookUpClassHelper.GetTypes(txtAssName.Text, txtNameSpare.Text);

            var dirPath = SETTINGS_DIR_PATH + "\\" + "HistoryClassFiles";
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
            foreach (Type t in ts)
            {
                string str = hlp.GetHisClassFileContext(t, txtAssName.Text);
                WriteTxt(new StringCollection { str }, dirPath + "\\" + t.Name + HistoryKeyInfo.LAST_STRING + ".cs", false, Encoding.UTF8);
            }

            MessageBox.Show("创建 History Class Files 成功");
        }

        private void btnHisFiles_Click(object sender, EventArgs e)
        {
            var hlp = new HistorySettingHelper();
            var hisAssName = LookUpClassHelper.ReplaceHistoryWord(txtAssName.Text);
            var hisNameSpare = LookUpClassHelper.ReplaceHistoryWord(txtNameSpare.Text);

            var sqlScript = GetDbTableCreateScript(hisAssName, hisNameSpare, null,HistoryKeyInfo.WithOutClassNames);
            var dirPath = SETTINGS_DIR_PATH + "\\" + "HistoryClassFiles";
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
            WriteTxt(new StringCollection { sqlScript }, dirPath + "\\" + "HistoryDbTableCreate.sql", false, Encoding.UTF8);

            var scMappingContext = GetMappingContext(hisAssName, hisNameSpare, HistoryKeyInfo.H_ID);
            WriteTxt(scMappingContext, dirPath + "\\" + hisAssName + ".hbm.xml", false, Encoding.UTF8);

            var scHisListSettingContext = hlp.GetHisListSettingFileContext(hisAssName,hisNameSpare);
            WriteTxt(scHisListSettingContext, dirPath + "\\HistoryObjProSet.xml", false, Encoding.UTF8);

            MessageBox.Show("创建 History Setting Files 成功");
        }
        const char FG = '┐';
        //const char FG = ',';

        private int GetLen(string rowString)
        {
            var tempAdd = 0;
            foreach (var c in rowString.ToCharArray())
            {
                var cInt = Convert.ToInt32(c);
                var ff = Convert.ToString(cInt, 16);
                if (ff.Length > 2)
                    tempAdd++;
            }
            return rowString.Length + tempAdd;
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            const int EACH_AMOUNT = 30000,MAX_AMOUNT = 30000;
            
            var scEachFileContext = new StringBuilder();
            var contextLen = 0;
            var fileIndex = 1;
            var ss = new string[]
                         {
                             "EQ", "PRO01", "PRO02", "PRO03", "PRO04", "PRO05", "PRO06", "PRO07", "PRO08", "PRO09", "PRO10"
                             , "PRO11", "PRO12"
                         };
            var scIndexInfo = new StringCollection();
            for (var i = 1; i <= MAX_AMOUNT; i++)
            {
                var sbRow = new StringBuilder();
                foreach(var s in ss)
                {
                    if (sbRow.Length > 0)
                        sbRow.Append(FG);
                    sbRow.Append(s + i.ToString().PadLeft(20 - s.Length, '0'));
                }
                sbRow.Append("我\r\n");
                scIndexInfo.Add(ss[0] + i.ToString().PadLeft(20 - ss[0].Length, '0') + FG + contextLen);
                contextLen += (GetLen(sbRow.ToString()));
                scEachFileContext.Append(sbRow);
                //scIndexInfo.Add(ss[0] + i.ToString().PadLeft(20 - ss[0].Length, '0') + FG + fileIndex);
                
                if(i%EACH_AMOUNT==0 || i== MAX_AMOUNT)
                {
                    
                    WriteTxt(new StringCollection{scEachFileContext.ToString()}, "c:\\vcInfo\\EquipInfo\\EquipInfo_"+fileIndex+".txt", false, Encoding.Default);
                    scEachFileContext = new StringBuilder();
                    fileIndex++;
                }
            }
            WriteTxt(scIndexInfo, "c:\\vcIndex\\EquipIndex.txt", false, Encoding.Default);

            Test();

            //MessageBox.Show("OK");
        }


        public void Test()
        {
            var sr = new StreamReader("c:\\vcIndex\\EquipIndex.txt",Encoding.Default);
            try
            {
                var scTemp = new StringCollection();
                var tempAmount = 0;
                while (sr.Peek() > 0 && tempAmount < 10)
                {
                    tempAmount++;
                    var val = sr.ReadLine();
                    var ss = val.Split(FG);
                    if (ss.Length == 2) scTemp.Add(ss[1]);
                }
                
                var sb = new StringBuilder();
                
                foreach(var index in scTemp)
                {
                    var sr2 = new StreamReader("c:\\vcInfo\\EquipInfo\\EquipInfo_" + 1 + ".txt",Encoding.Default);
                    try
                    {
                        var lIndex = Convert.ToInt64(index);
                        sr2.BaseStream.Position = (lIndex);
                        var val = sr2.ReadLine();
                        sb.Append(val+ "___"+val.Length+"___" +"\r\n\r\n");
                        //sr2.BaseStream.Position = 0;
                    }
                    finally
                    {
                        sr2.Close();
                        sr2.Dispose();
                    }
                    
                }
                MessageBox.Show(sb.ToString());
            }
            finally
            {
                sr.Close();
                sr.Dispose();
            }
        }

        private void btnHelp01_Click(object sender, EventArgs e)
        {
            MessageBox.Show("指定项目中的Entity类生成所需要的Sql脚本\r\n注意:\r\n先编写好业务对象");
        }

        private void btnHelp02_Click(object sender, EventArgs e)
        {
            MessageBox.Show("指定项目中的Entity类生成所需要的对象持久化的Mapping文件\r\n注意:\r\n先编写好业务对象");
        }

        private void btnHelp03_Click(object sender, EventArgs e)
        {
            MessageBox.Show("指定项目中的Entity类面页(列表页面与编辑页面)解释需要用的BaseDataSetting.xml配置文件\r\n"
                + "注意:\r\n先编写好业务对象;\r\n" 
                +"第1步生成sql脚本运行在数据库;\r\n"
                +"第2步生成的Mapping文件存放到指定的文件夹;");
        }

        private void btnHelp04_Click(object sender, EventArgs e)
        {
            MessageBox.Show("指定项目中的Entity类生成所对象解析批量导入类所需要的设置文件[ImportorSetting.xml]\r\n"
                +"注意:\r\n先编写好业务对象;\r\n");
        }

        private void btnHelp05_Click(object sender, EventArgs e)
        {
            MessageBox.Show("指定项目中的Entity类生成History项目所需要的Class文件\r\n"
                + "注意:\r\n当Core项目中的业务对象都已经确认后才进行历史模块的构建;\r\n");
        }

        private void btnHelp06_Click(object sender, EventArgs e)
        {
            MessageBox.Show("指定项目中的HistoryEntity类生成所需要相关文件(Sql脚本与Mapping脚本)\r\n"
                +"注意:\r\n先把第5步生成的HistoryEntity类导入History项目中");
        }
    }
}